package com.ruoyi.flow.flow.form;

import com.ruoyi.flow.common.SelectOption;
import com.ruoyi.flow.flow.FlowConstants;
import com.ruoyi.flow.flow.workflow.FlowService;
import com.google.common.collect.Lists;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.User;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.runtime.ProcessInstance;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @Author: wtian
 * @Description:
 * @Date: Created in 15:20 2018/8/15
 * @Version: 1.0
 */
@Controller
@RequestMapping("/flow/forms")
public class FlowFormController {

    /**
     * 根据定义流程时在任务节点上设置的表单标识，跳转到表单页面。
     * 规则如下：
     * <ul>
     * <li>跳转到表单页面的URL地址是 {contextPath}/forms/{表单标识}</li>
     * <li>返回的页面同一在WEB-INF/views/forms/目录下，以表单标识的全小写作为文件名</li>
     * </ul>
     *
     * @param formName
     * @param taskId
     * @return
     */
    @RequestMapping(value = "/{formName}")
    public ModelAndView toFormPage(@PathVariable String formName, @RequestParam Optional<String> taskId, @RequestParam Optional<String> definitionKey) {
        String page = "admin/forms/" + StringUtils.lowerCase(formName);
        ModelAndView modelAndView = new ModelAndView(page);
        if (taskId.isPresent()) {
            // 判断下一步是如何获取用户,如果是排他网关，则获取顺利进行的节点的用户如何获取
            String _taskId = taskId.get();
            modelAndView.addObject("taskId", _taskId);
            String instanceId = FlowService.taskService().getTaskByTaskId(_taskId).getProcessInstanceId();
            Map<String, Object> variables = FlowService.instanceService().getStartVariables(instanceId);
            modelAndView.addObject("variables", variables);
        }
        if (definitionKey.isPresent()) {
            modelAndView.addObject("definitionKey", definitionKey.get());
        }
        return modelAndView;
    }

    /**
     * 跳转到办理人选择页面
     *
     * @param selectType
     * @return
     */
    @RequestMapping(value = "/assignee/page")
    public ModelAndView toAssigneeSelectPage(@RequestParam String selectType) {
        ModelAndView modelAndView = new ModelAndView("admin/forms/selectassignee");
        modelAndView.addObject("selectType", selectType);
        List<SelectOption> options = Lists.newArrayList();
        if (StringUtils.equals(selectType, FlowConstants.Assignee.SELECTMULTIUSER.getAssignee()) || StringUtils.equals(selectType, FlowConstants.Assignee.SELECTSINGLEUSER.getAssignee())) {
            List<User> users = FlowService.identityService().getUsers(null, null);
            for (User user : users) {
                options.add(new SelectOption(user));
            }
        } else {
            List<Group> groups = FlowService.identityService().getGroups();
            for (Group group : groups) {
                options.add(new SelectOption(group));
            }
        }
        modelAndView.addObject("options", options);
        return modelAndView;
    }

    /**
     * 跳转到发起流程时填写的业务表单详情页面，规则如下:
     * <ul>
     * <li>跳转到的页面统一在/WEB-INF/views/business目录下，并且以模型标识（也就是definitionKey）作为文件名</li>
     * </ul>
     *
     * @param taskId
     * @return
     */
    @RequestMapping(value = "/startFormDetail")
    public ModelAndView toStartFormDetailPage(@RequestParam Optional<String> taskId, @RequestParam Optional<String> instanceId) {
        String _instanceId = "";
        String _taskId = "";
        if (taskId.isPresent()) {
            _taskId = taskId.get();
            TaskEntity taskEntity = FlowService.taskService().getTaskByTaskId(_taskId);
            _instanceId = taskEntity.getProcessInstanceId();
        } else if (instanceId.isPresent()) {
            _instanceId = instanceId.get();

        }

        String definitionId = null;
        String businessKey = null;
        ProcessInstance instance = FlowService.instanceService().getProcessInstanceByInstanceId(_instanceId);
        if (instance == null) {
            HistoricProcessInstance historicProcessInstance = FlowService.instanceService().getHistoricProcessInstanceByInstanceId(_instanceId);
            definitionId = historicProcessInstance.getProcessDefinitionId();
            businessKey = historicProcessInstance.getBusinessKey();
        } else {
            definitionId = instance.getProcessDefinitionId();
            businessKey = instance.getBusinessKey();
        }
        ProcessDefinitionEntity definition = FlowService.definitionService().getProcessDefinitionByDefinitionId(definitionId);
        String definitionKey = definition.getKey();
        // 通过获取第一个节点的变量来获取业务信息
        Map<String, Object> variables = FlowService.instanceService().getStartVariables(_instanceId);
        ModelAndView modelAndView = new ModelAndView("admin/business/" + definitionKey);
        modelAndView.addObject("variables", variables);
        modelAndView.addObject("businessKey", businessKey);
        modelAndView.addObject("taskId", _taskId);
        modelAndView.addObject("instanceId", _instanceId);
        return modelAndView;
    }


    /**
     * 获取发起表单或者任务表单的内容
     *
     * @param instanceOrTaskId
     * @param startOrTask
     * @return
     */
    @RequestMapping(value = "/data/{startOrTask}/{instanceOrTaskId}")
    @ResponseBody
    public Map<String, Object> getFormData(@PathVariable String instanceOrTaskId, @PathVariable String startOrTask) {
        Map<String, Object> variables = FlowService.formService().getFormData(instanceOrTaskId, startOrTask);
        return variables;
    }

    /**
     * 跳转到委托办理人选择页面
     *
     * @param taskId 任务ID
     * @return
     */
    @RequestMapping(value = "/assignee/delegate")
    public ModelAndView toAssigneeDelegatePage(@RequestParam String taskId) {
        ModelAndView modelAndView = new ModelAndView("admin/forms/delegate");
        modelAndView.addObject("taskId", taskId);
        List<SelectOption> options = Lists.newArrayList();
        List<User> users = FlowService.identityService().getUsers(null, null);
        for (User user : users) {
            options.add(new SelectOption(user));
        }
        modelAndView.addObject("options", options);
        return modelAndView;
    }
}
